package types

import (
	"Identity/common"
	"github.com/ethereum/go-ethereum/rlp"
	"golang.org/x/crypto/sha3"
	"math/big"
	"reflect"
	"sync/atomic"
)

type Header struct {
	ParentHash  common.Hash    `json:"parentHash"       gencodec:"required"`
	UncleHash   common.Hash    `json:"sha3Uncles"       gencodec:"required"`
	Coinbase    common.Address `json:"miner"            gencodec:"required"`
	Root        common.Hash    `json:"stateRoot"        gencodec:"required"`
	TxHash      common.Hash    `json:"transactionsRoot" gencodec:"required"`
	//ReceiptHash common.Hash    `json:"receiptsRoot"     gencodec:"required"`
	//Bloom       Bloom          `json:"logsBloom"        gencodec:"required"`
	Number      *big.Int       `json:"number"           gencodec:"required"`
	//GasLimit    uint64         `json:"gasLimit"         gencodec:"required"`
	//GasUsed     uint64         `json:"gasUsed"          gencodec:"required"`
	Time        uint64         `json:"timestamp"        gencodec:"required"`
	Extra       []byte         `json:"extraData"        gencodec:"required"`
	MixDigest   common.Hash    `json:"mixHash"`

	Difficulty  *big.Int       `json:"difficulty"       gencodec:"required"`
	Nonce       BlockNonce     `json:"nonce"`
}


var headerSize  = common.StorageSize(reflect.TypeOf(Header{}).Size())
func (h * Header)Size() common.StorageSize{
	return headerSize + common.StorageSize(len(h.Extra) + len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen())/8)
}

func rlpHash(x interface{}) (h common.Hash) {
	hw := sha3.NewLegacyKeccak256()
	rlp.Encode(hw, x)
	hw.Sum(h[:0])
	return h
}

// Hash returns the block hash of the header, which is simply the keccak256 hash of its
// RLP encoding.
func (h *Header) Hash() common.Hash {
	return rlpHash(h)
}

type Body struct {

}


type Block struct {
	header *Header
	Tokens

	// caches
	hash atomic.Value
	size atomic.Value
}